package Biblioteca

import Contas.Administrador 
import Contas.Usuario 
import Contas.UsuarioComum 
import java.text.SimpleDateFormat 
import java.util.ArrayList 
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter 

class EmprestimoController {
	
	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
	
	static emprestimoResult
	static consulta
	
	def livros = Livro.executeQuery("select titulo from Livro")
	def relatorios = RelatorioTecnico.executeQuery("select titulo from RelatorioTecnico")
	def itens = livros + relatorios
	def usuariosComum = UsuarioComum.executeQuery("select username from UsuarioComum")
	def administradores = UsuarioComum.executeQuery("select username from Administrador")
	def usuarios = usuariosComum + administradores
	def livrosEmprestimo = new ArrayList();
	def errosExtras = new ArrayList();
	def listaAux = new ArrayList();
	
	
	def index = {
		redirect(action: "list", params: params)
	}
	
	private String getTipoUsuario (){
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipo
		if (Administrador.get(user.id)==null){
			tipo = "Usuario"
		}else{
			tipo = "Admin"
		}
	return tipo
	}
	
	def list = {
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def list_emprestimos = new ArrayList()
		def list_emp_valido = new ArrayList()
                
		def usuarioComumInstance
		def String tipo
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
                
                for(emprestimo in Emprestimo.list(params)){
                    if(emprestimo.valido){
                        list_emp_valido.add(emprestimo)
                    }
                }

		if (Administrador.get(user.id)==null){
			tipo = "Usuario"
			usuarioComumInstance = UsuarioComum.get(user.id)
			for (emprestimo in list_emp_valido){
				if (emprestimo.login == username.toString()){
					list_emprestimos.add(emprestimo)
				}
			}
		}else{
			tipo = "Admin"
			usuarioComumInstance = Administrador.get(user.id)
			list_emprestimos = list_emp_valido
		}
		
		
		
		[emprestimoInstanceList: list_emprestimos, emprestimoInstanceTotal: Emprestimo.count(), tipoUsuario:this.getTipoUsuario ()]
	}
	
	def create = {
		
		def emprestimoInstance = new Emprestimo()
		emprestimoInstance.properties = params
		return [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios,  errosExtras:errosExtras, tipoUsuario:this.getTipoUsuario ()]
	}
	
	def search = {return [tipoUsuario:this.getTipoUsuario ()]}
	
	def search_advanced ={
		return [tipoUsuario:this.getTipoUsuario ()]		
	}	
	
	def results ={
		if (!params.max) params.max = 50
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "titulo"
		if (!params.order) params.order = "asc"
		
		consulta = params
		println(params)
		println(consulta)
		
		def criteria = Emprestimo.createCriteria()
		
		emprestimoResult = criteria {
			maxResults(params.max?.toInteger())
			firstResult(params.offset?.toInteger())
			order(params.sort, params.order)
			and{ like('titulo','%' + params.titulo + '%') }
		}
		
		[pesquisaEmprestimo: emprestimoResult,params : params, tipoUsuario:this.getTipoUsuario ()]
	}
	
	def results_emprestimo ={	
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		
		consulta = params
		
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipoUsuario
		if (Administrador.get(user.id)==null){
			tipoUsuario = "Usuario"
		}else{
			tipoUsuario = "Admin"
		}
		
		if (!params.max) params.max = 50
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "titulo"
		if (!params.order) params.order = "asc"
		
		def criteria = Emprestimo.createCriteria()
		
		emprestimoResult = criteria {
			maxResults(params.max?.toInteger())
			firstResult(params.offset?.toInteger())
			order(params.sort, params.order)
			and{
				like('titulo','%' + params.titulo + '%')
				like('tipo','%' + params.tipo + '%')
				like('login','%' + params.login + '%')
				
				java.text.DateFormat df = new java.text.SimpleDateFormat("dd/MM/yyyy");								
				
				if(params.dataEmprestimo != null && !params.dataEmprestimo.equals(df.parse("01/01/1910"))){
					between('dataEmprestimo', new Date(params.dataEmprestimo.getTime()-((1000*24*60*60)*1)), new Date(params.dataEmprestimo.getTime()+((1000*24*60*60)*1)))
				}
				
				if(params.dataDevolucao != null && !params.dataDevolucao.equals(df.parse("01/01/1910"))){
					between('dataDevolucao', new Date(params.dataDevolucao.getTime()-((1000*24*60*60)*1)), new Date(params.dataDevolucao.getTime()+((1000*24*60*60)*1)))
				}								
				
				if(tipoUsuario != "Admin"){										
					like('login', username)
				}
				
			}
		}			
		
		[pesquisaEmprestimo: emprestimoResult,params : params, tipoUsuario:this.getTipoUsuario ()]
	}
	
	
	def save = {
		def emprestimoInstance = new Emprestimo(params)
		emprestimoInstance.dataEmprestimo = new Date()
		emprestimoInstance.dataDevolucao = new Date()
		emprestimoInstance.dataDevolucao = emprestimoInstance.dataDevolucao.plus (Integer.parseInt (params.diasEmail))
                emprestimoInstance.valido = true
		emprestimoInstance.titulo = params.item
		def tipo
		def livroAux = Livro.executeQuery("select id from Livro where titulo = " + "'" + params.item + "'")
		if (livroAux.size() == 0){
			def relatorioTecnicoAux = RelatorioTecnico.executeQuery("select id from RelatorioTecnico where titulo = " + "'" + params.item + "'")
			emprestimoInstance.idItem = relatorioTecnicoAux[0]
			tipo = 'relatorio'
		}else{
			emprestimoInstance.idItem = livroAux[0]
			tipo = 'livro'
		}
		emprestimoInstance.tipo = tipo
		if (tipo == 'livro'){
			
			def livroInstance = Livro.get(emprestimoInstance.idItem)
			def qtde = Exemplar.executeQuery("select id from Exemplar where isbnItem = '" + livroInstance.isbn+"'")
			def emprestados = Emprestimo.executeQuery("select id from Emprestimo where idItem = " + livroInstance.id +" and tipo = '"+tipo+"'"+" and valido =1")
			def reservados = Reserva.executeQuery("select id from Reserva where idItem = " + livroInstance.id + " and tipo = '"+tipo+"'")
			def jatemEmprestimo = false
			def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
			def emprestimos_usuario = Emprestimo.executeQuery("select id from Emprestimo where login = " + "'" + username.toString() + "'"+" and valido = 1")
			def reservas_usuario = Reserva.executeQuery("select idItem from Reserva where username = " + "'" + username.toString() +"'")
			for (emprestimo in emprestimos_usuario){
				def livro_emprestimo = Emprestimo.executeQuery("select idItem from Emprestimo where id = " + emprestimo + " and tipo = '"+tipo+"'"+" and valido = 1")
				if (livro_emprestimo.contains (livroInstance.id)){
					flash.message = "Voce ja possui um emprestimo deste livro."
					jatemEmprestimo = true
				}
			}
			
			if ((!jatemEmprestimo && (qtde.size() - emprestados.size() - reservados.size()) > 0) || reservas_usuario.contains(livroInstance.id)){
				if (emprestimoInstance.save(flush: true)) {
					
					if (reservas_usuario.contains(livroInstance.id)){
						Reserva.get(livroInstance.id).delete()
					}
					
					flash.message = "${message(code: 'default.created.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), emprestimoInstance.id])}"
					redirect(action: "show", id: emprestimoInstance.id)
				}
				else {
					render(view: "create", model: [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios,tipoUsuario:this.getTipoUsuario ()])
				}
			}else if (!jatemEmprestimo){
				flash.message = "Nao existe nenhum exemplar disponivel para este Livro."
				
			}else {
				render(view: "create", model: [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios, tipo:tipo, tipoUsuario:this.getTipoUsuario ()])
			}
			
		}else{
			def relatorioInstance = RelatorioTecnico.get(emprestimoInstance.idItem)
			def emprestados = Emprestimo.executeQuery("select id from Emprestimo where idItem = " + relatorioInstance.id +" and tipo = '"+tipo+"'")
			def reservados = Reserva.executeQuery("select id from Reserva where idItem = " + relatorioInstance.id + " and tipo = '"+tipo+"'")
			def jatemEmprestimo = false
			def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
			def emprestimos_usuario = Emprestimo.executeQuery("select id from Emprestimo where login = " + "'" + username.toString() + "'")
			def reservas_usuario = Reserva.executeQuery("select idItem from Reserva where username = " + "'" + username.toString() +"'" )
			for (emprestimo in emprestimos_usuario){
				def relatorio_emprestimo = Emprestimo.executeQuery("select idItem from Emprestimo where id = " + emprestimo + " and tipo = 'relatorio'")
				if (relatorio_emprestimo.contains (relatorioInstance.id)){
					flash.message = "Voce ja possui um emprestimo deste relatorio tecnico."
					jatemEmprestimo = true
				}
			}
			
			if ((!jatemEmprestimo && (1 - emprestados.size() - reservados.size()) > 0) || reservas_usuario.contains(relatorioInstance.id)){
				if (emprestimoInstance.save(flush: true)) {
					
					if (reservas_usuario.contains(relatorioInstance.id)){
						Reserva.get(livroInstance.id).delete()
					}
					flash.message = "${message(code: 'default.created.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), emprestimoInstance.id])}"
					redirect(action: "show", id: emprestimoInstance.id)
				}
				else {
					render(view: "create", model: [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios, tipo:tipo, tipoUsuario:this.getTipoUsuario ()])
				}
			}else if (!jatemEmprestimo){
				flash.message = "Item indisponivel."
				
			}else {
				render(view: "create", model: [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios, tipo:tipo, tipoUsuario:this.getTipoUsuario ()])
			}
		}
	}
	
	
	
	def show = {
		def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
		Usuario user = Contas.Usuario.findByUsername(username)
		def tipoUsuario
		if (Administrador.get(user.id)==null){
			tipoUsuario = "Usuario"
		}else{
			tipoUsuario = "Admin"
		}
		
		def livros = Livro.executeQuery("select titulo from Livro")
		def relatorios = RelatorioTecnico.executeQuery("select titulo from RelatorioTecnico")
		def emprestimoInstance = Emprestimo.get(params.id)
		def nome_item
		def tipo
		def livroAux = Livro.executeQuery("select titulo from Livro where id = " + "'" + emprestimoInstance.idItem + "'")
		nome_item = livroAux[0]
		if (livros.contains(emprestimoInstance.titulo)){
			tipo = 'livro'
		}else{
			def relatorioTecnicoAux = RelatorioTecnico.executeQuery("select titulo from RelatorioTecnico where id = " + "'" + emprestimoInstance.idItem + "'")
			nome_item = relatorioTecnicoAux[0]
			tipo = 'relatorio'
		}
		
		if (!emprestimoInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
			redirect(action: "list")
		}
		else {
			[emprestimoInstance: emprestimoInstance, nome_item:nome_item, tipo:tipo, tipoUsuario:this.getTipoUsuario ()]
		}
	}
	
	def edit = {
		def emprestimoInstance = Emprestimo.get(params.id)
		if (!emprestimoInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
			redirect(action: "list")
		}
		else {
			return [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios, errosExtras:errosExtras, tipoUsuario:this.getTipoUsuario ()]
		}
	}
	
	def update = {
		def emprestimoInstance = Emprestimo.get(params.id)
		
		if (emprestimoInstance) {
			if (params.version) {
				def version = params.version.toLong()
				if (emprestimoInstance.version > version) {
					
					emprestimoInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'emprestimo.label', default: 'Emprestimo')] as Object[], "Another user has updated this Emprestimo while you were editing")
					render(view: "edit", model: [emprestimoInstance: emprestimoInstance, tipoUsuario:this.getTipoUsuario ()])
					return
				}
			}
			if (params.itens.getClass().toString().equals('class [Ljava.lang.String;')){
				errosExtras = new ArrayList()
				
			}else{
				if (params.itens == null){
					errosExtras.add('Selecione ao menos um item.')
				}else{
					emprestimoInstance.list.add (params.itens.toString())
					errosExtras = new ArrayList()
				}
			}
			emprestimoInstance.properties = params
			if (!emprestimoInstance.hasErrors() && emprestimoInstance.save(flush: true)) {
				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), emprestimoInstance.id])}"
				redirect(action: "show", id: emprestimoInstance.id)
			}
			else {
				render(view: "edit", model: [emprestimoInstance: emprestimoInstance, itens:itens, usuarios:usuarios, errosExtras:errosExtras, tipoUsuario:this.getTipoUsuario ()])
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
			redirect(action: "list")
		}
	}
	
	def delete = {
		def emprestimoInstance = Emprestimo.get(params.id)
		if (emprestimoInstance) {
			try {
				emprestimoInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
				redirect(action: "list")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
				redirect(action: "show", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
			redirect(action: "list")
		}
	}
	
	def createReportEmprestimoSimple = {
		def emprestimos = emprestimoResult
		
		String caminhoLogoSPL = System.getProperty("user.dir") + "\\web-app\\reports\\logo_spl_report.jpg";
		String caminhoLogoGMF = System.getProperty("user.dir") + "\\web-app\\reports\\gmf.jpg";
		
		params.put("logoSPL", caminhoLogoSPL);
		params.put("logoGMF", caminhoLogoGMF);
		params.put("tituloConsulta", consulta.titulo);
		
		chain(controller:'jasper',action:'index',model:[data:emprestimos],params:params)
	}

        def devolucao = {

//            def empCriteria = Emprestimo.createCriteria()
//            def empInstance = empCriteria{
//                and{
//                   like('login',params.login)
//                    like('titulo',params.titulo)
//                    like('dataEmprestimo',params.dataEmprestimo)
//                    like('dataDevolucao',params.dataDevolucao)
//                }
//            }
            def emprestimoInstance = Emprestimo.get(params.id)
            emprestimoInstance.valido = false
            if (emprestimoInstance.save(flush: true))
            flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'emprestimo.label', default: 'Emprestimo'), params.id])}"
            redirect(action: "list")

        }

	def createReportEmprestimoComplete = {
		def emprestimos = emprestimoResult
		
		String caminhoLogoSPL = System.getProperty("user.dir") + "\\web-app\\reports\\logo_spl_report.jpg";
		String caminhoLogoGMF = System.getProperty("user.dir") + "\\web-app\\reports\\gmf.jpg";
		
		params.put("logoSPL", caminhoLogoSPL);
		params.put("logoGMF", caminhoLogoGMF);
		params.put("tituloConsulta", consulta.titulo);
		params.put("tipoConsulta",consulta.tipo);
		params.put("loginConsulta",consulta.login);
		
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy")
		
		String dataEmprestimo = ""
		
		if(consulta.dataEmprestimo){
			dataEmprestimo = formato.format(consulta.dataEmprestimo)
		}
		
		if(dataEmprestimo == "01/01/1910"){
			dataEmprestimo = ""
		}
	
								
		params.put("dataEmprestimoConsulta",dataEmprestimo);		
		
		
		String dataDevolucao = ""
		
		if(consulta.dataDevolucao){
			dataDevolucao = formato.format(consulta.dataDevolucao)
		}
		
		if(dataDevolucao == "01/01/1910"){
			dataDevolucao = ""
		}

		params.put("dataDevolucaoConsulta",dataDevolucao);
		
		
		chain(controller:'jasper',action:'index',model:[data:emprestimos],params:params)
	}
}
